<template>
  <ModalCard action @close="emits('close')" @submit="submit">
    <div style="padding: 43rem 36rem 20rem">
      <NSpin :show="spinShow">
        <div class="scope-box">
          <div style="margin-bottom: 10rem; display: flex">
            <div style="flex: 0 0 50%;display: flex;align-items: center;">
              <span style="width: auto;margin-right: 20px;">
                {{ radioName }}
              </span>
              <n-input v-model:value="pattern" placeholder="输入关键字搜索" style="width: 50%;" />
            </div>
            <div style="flex: 0 0 50%;display: flex;align-items: center;">
              <span>已选范围 (双击取消) ({{ seleteTransfer?.length || 0 }})</span>
              <NIcon size="24" style="cursor: pointer;margin: 0 5px;" @click="up">
                <ArrowUpwardSharp />
              </NIcon>
              <NIcon size="24" style="cursor: pointer" @click="low">
                <ArrowDownwardOutlined />
              </NIcon>
            </div>
          </div>
          <div style="margin-bottom: 10rem; display: flex">
            <div class="tree-box">
              <NScrollbar>
                <NTree style="height: 400rem;" ref="transfer" :data="options" checkable
                  v-model:checked-keys="seleteTransfer" :cascade="!props.radioFlat ? true : false" checkStrategy="child"
                  expand-on-click block-line :on-update-checked-keys="handleCheckedKeys" :checkOnClick="false"
                  :selectable="false" keyField="value" :defaultCheckedKeys="defaultCheckedKeys" :pattern="pattern" />
              </NScrollbar>
            </div>
            <div class="tree-box" id="selectRef">
              <NScrollbar>
                <template v-if="seleteTransfer?.length">
                  <div v-for="(item, index) in selectList" :key="index">
                    <div v-if="seleteTransfer.includes(item.identifyingId)" class="selete-box"
                      @dblclick="handleDblClick(item.identifyingId)" @click="clickInd(index)"
                      :style="{ backgroundColor: clickIndex == index ? '#5fb17f' : 'transparent' }">
                      <div style="display: flex; margin-left: 6rem; flex: 0 0 40%">
                        {{ item.typeName }}
                      </div>
                      <div style="display: flex; flex: 1; align-items: center" v-if="props.selectFlat">
                        <div style="width: auto">消息提示：</div>
                        <NSelect style="width: 150rem; z-index: 1000" placeholder="选择消息提示" :options="selectOptions"
                          v-model:value="item.noticeCode" />
                      </div>
                    </div>
                  </div>
                </template>
              </NScrollbar>
            </div>
          </div>
          <n-radio-group v-model:value="seleteRadio" name="radiogroup" :on-update:value="handleRadio">
            <NSpace>
              <n-radio v-for="item in radioList" :key="item.value" :value="item.value">
                {{ item.label }}
              </n-radio>
            </NSpace>
          </n-radio-group>
        </div>
      </NSpin>
    </div>
  </ModalCard>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import {
  useMessage,
  NTree,
  NSpace,
  NRadio,
  NRadioGroup,
  NSelect,
  NSpin,
  NInput,
  NScrollbar,
  NIcon
} from 'naive-ui'
import ModalCard from '@/components/ModalCard.vue'
import { sendRequest } from '@/utils/api'
import type { HttpResponse } from '@/utils/http'
import type { ScopeModel } from '@/api/scope'
import { ArrowUpwardSharp, ArrowDownwardOutlined } from '@vicons/material'

const message = useMessage()
const pattern = ref()
const emits = defineEmits(['close', 'scopeSubmit'])
const props = defineProps({
  flat: { type: Boolean, default: () => false }, //是否只显示选择人员
  selectFlat: { type: Boolean, default: () => false }, //是否显示select
  defaultList: { type: Array, default: () => [] }, //默认选择数据
  radioFlat: { type: Boolean, default: () => false }, //是否只能单选
  readFlat: { type: Boolean, default: () => false } //是否是阅办代办
})
const seleteTransfer: any = ref()
const defaultCheckedKeys = props.defaultList
  ? [...props.defaultList.map((it: any) => it.fullId)]
  : seleteTransfer.value
const seleteRadio = ref()
const radioList = ref([
  {
    label: '人员',
    value: 'ULA0102',
    key: 'ry'
  },
  {
    label: '角色',
    value: 'ULA0103',
    key: 'js'
  },
  {
    label: '岗位',
    value: 'ULA0101',
    key: 'gw'
  },
  {
    label: '常用组合',
    value: 'ULA0104',
    key: 'zh'
  }
])
const selectOptions = [
  { label: '默认消息提示', value: 'A1101' },
  { label: '弹窗提示', value: 'A1102' },
  { label: '短信提示', value: 'A1103' }
]
// 单机选择
const clickIndex = ref()
const clickInd = (index: any) => {
  clickIndex.value = index
}
// 上移
const up = () => {
  if (!clickIndex.value) return
  selectList.value.splice(clickIndex.value, 1, ...selectList.value.splice(clickIndex.value - 1, 1, selectList.value[clickIndex.value]))
  seleteTransfer.value.splice(clickIndex.value, 1, ...seleteTransfer.value.splice(clickIndex.value - 1, 1, seleteTransfer.value[clickIndex.value]))
  clickIndex.value = clickIndex.value - 1
}
// 下移
const low = () => {
  if (clickIndex.value == null || clickIndex.value == selectList.value?.length - 1) return
  selectList.value.splice(clickIndex.value, 1, ...selectList.value.splice(clickIndex.value + 1, 1, selectList.value[clickIndex.value]))
  seleteTransfer.value.splice(clickIndex.value, 1, ...seleteTransfer.value.splice(clickIndex.value + 1, 1, seleteTransfer.value[clickIndex.value]))
  clickIndex.value = clickIndex.value + 1
}
// 处理data数据
function createData(data: any): any | undefined {
  if (!data?.length) return undefined
  return data.map((item: any) => {
    return {
      label: item.typeName,
      value: item.identifyingId,
      children: createData(item.children)
    }
  })
}
// 处理树形结构
const options: any = ref(undefined)
function flattenTree(list: any) {
  const result: any = []
  function flatten(_list: any = []) {
    _list.forEach((item: any) => {
      result.push(item)
      flatten(item.children)
    })
  }
  flatten(list)
  return result
}
// 获取数据
const spinShow = ref(false)
const allScope: any = ref([])
const scopeList = ref()
const getScopeList = async () => {
  spinShow.value = true
  /** @readFlat  true或false  阅办代办的人员列表走单独的接口 */
  if (props.readFlat) {
    const [error, res] = await sendRequest<HttpResponse<ScopeModel>>({
      module: 'scope',
      api: 'ReadScopeOrPeople',
      override: {
        params: {
          code: seleteRadio.value
        }
      }
    })
    if (error) return message.error(error.message)
    if (res.code !== 0) return message.error(res.msg)
    scopeList.value = res.data
    const key = radioList.value.find((it: any) => it.value == seleteRadio.value)?.key
    options.value = createData(res.data[key as never])
    if (!allScope.value.length) allScope.value.push(...flattenTree(res.data.ry))
  } else {
    const [error, res] = await sendRequest<HttpResponse<ScopeModel>>({
      module: 'scope',
      api: 'scopeOrPeople',
      override: {
        params: {
          code: seleteRadio.value
        }
      }
    })
    if (error) return message.error(error.message)
    if (res.code !== 0) return message.error(res.msg)
    scopeList.value = res.data
    const key = radioList.value.find((it: any) => it.value == seleteRadio.value)?.key
    options.value = createData(res.data[key as never])
    if (!allScope.value.length)
      Object.keys(res.data).forEach((it: any) =>
        allScope.value.push(...flattenTree(res.data[it as never]))
      )
  }
  spinShow.value = false
}
// 单选框选择
const radioName: any = ref('人员')
const handleRadio = (val: any) => {
  seleteRadio.value = val
  radioName.value = radioList.value.find((it: any) => it.value == val)?.label
  getScopeList()
}
// tree选择
const handleCheckedKeys = (v: any) => {
  seleteTransfer.value = v
  handleRightList(true)
}
// 双击取消选择
const handleDblClick = (id: any) => {
  const index = seleteTransfer.value.findIndex((it: any) => it == id)
  if (index !== -1) seleteTransfer.value.splice(index, 1)
}
// 获取右侧循环数据
const selectList: any = ref([])
const handleRightList = (isFalt = false) => {
  const tmp: any = []
  if (props.radioFlat) {
    seleteTransfer.value.map((it: any, index: any) => {
      if (index == seleteTransfer.value.length - 1) return
      seleteTransfer.value.splice(seleteTransfer.value[index], 1)
    })
  }
  seleteTransfer.value.map((it: any) => {
    const T = allScope.value.find((c: any) => c.identifyingId == it)
    if (props.selectFlat && isFalt) T.noticeCode = 'A1101'
    T && tmp.push(T)
  })
  console.log(tmp)
  selectList.value = tmp
}
// 确定
const submit = async () => {
  if (!seleteTransfer.value) return message.error('暂无选择数据')

  const result = seleteTransfer.value.map((it: any) => {
    const tmp = allScope.value?.find((c: any) => c?.identifyingId == it)
    delete tmp?.children
    return tmp
  })

  result.map((it: any) => {
    it.fullId = it.identifyingId
    it.identifyingId = it.identifyingId?.split('-')[it.identifyingId?.split('-').length - 1]
  })
  emits('scopeSubmit', result)
}

onMounted(async () => {
  if (props.flat) radioList.value = [{ label: '人员', value: 'ULA0102', key: 'ry' }]
  seleteRadio.value = radioList.value[0].value
  await getScopeList()
  if (props.defaultList?.length) {
    seleteTransfer.value = [...props.defaultList.map((it: any) => it.fullId)]
    props.defaultList.map((it: any) => {
      const T = allScope.value.find((c: any) => c.identifyingId === it.fullId)
      T && (T.noticeCode = it.noticeCode)
    })
    handleRightList()
  }
})
</script>

<style scoped lang="css">
.scope-box {
  display: flex;
  flex-direction: column;
  background-color: #ebeceb;
  padding: 20rem;
  width: 900rem;
  height: 720rem;
  box-sizing: border-box;
}

.tree-box {
  flex: 0 0 50%;
  background-color: #fff;
  height: 600rem;
  border-right: 1rem solid #ccc;
  overflow-y: scroll;
}

.zhTitle {
  display: flex;
  align-items: center;
  width: 100%;
  height: 40rem;
  cursor: pointer;
  border-radius: 4rem;
  padding: 10rem;
}

.zhTitle:hover {
  animation: show 0.5s forwards;
}

.selete-box {
  width: 100%;
  display: flex;
  justify-content: space-between;
  padding: 10rem 0;
  align-items: center;
  border-radius: 4rem;
  /* animation: hide 0.5s forwards; */
}

.selete-box:hover {
  animation: show 0.5s forwards;
}

@keyframes show {
  to {
    background-color: #e7f3ec;
  }
}

@keyframes hide {
  from {
    background-color: #e7f3ec;
  }

  to {
    background-color: transparent;
  }
}

.tree-box::-webkit-scrollbar {
  display: none;
}

.tree-box::-webkit-scrollbar {
  display: none;
}

:deep(.n-scrollbar-container) {
  width: 100%;
  height: 100%;
}

:deep(.n-scrollbar-content) {
  width: 100%;
  height: 100%;
}

:deep(.n-tree) {
  min-height: 400rem;
  height: auto !important;
  display: flex;
  flex-wrap: wrap;
  flex-direction: column;
}
</style>
